﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Slave
{
    public partial class NumberBox :TextBox
    {

        private const int WM_CONTEXTMENU = 0x007b;//右键菜单消息 
        private const int WM_CHAR = 0x0102;       //输入字符消息（键盘输入的，输入法输入的好像不是这个消息）
        private const int WM_CUT = 0x0300;        //程序发送此消息给一个编辑框或combobox来删除当前选择的文本
        private const int WM_COPY = 0x0301;       //程序发送此消息给一个编辑框或combobox来复制当前选择的文本到剪贴板
        private const int WM_PASTE = 0x0302;      //程序发送此消息给editcontrol或combobox从剪贴板中得到数据
        private const int WM_CLEAR = 0x0303;      //程序发送此消息给editcontrol或combobox清除当前选择的内容；
        private const int WM_UNDO = 0x0304;        //程序发送此消息给editcontrol或combobox撤消最后一次操作


        private byte[] nulongbytes = new byte[8];
        private byte[] nuintbytes = new byte[4];
        private byte[] nushortbytes = new byte[2];
        private byte[] nbytes = new byte[1];

        private ushort nushort;
        private byte nubyte;
        private uint nuint;
        private ulong nulong;

        public NumberBox()
        {
            this.TextAlign = HorizontalAlignment.Right;
        }


        public enum NumberType
        {
            intNumber,
            DecimalNumber,
            hexNumber
        }

        #region 属性

        private NumberType numberType = NumberType.intNumber;
        [Description("数字类型")]
        /// <summary>
        /// 数字类型。
        /// </summary>
        public NumberType Numbertype
        {
            get {
                TypeChange();
                return numberType;
            }
            set {
                TypeChange();
                numberType = value;
            }
        }



        private int iNumberLength = 10;

        [Description("数据长度")]
        /// <summary>
        /// 数据长度
        /// </summary>
        public int INumberLength
        {
            set
            {
                iNumberLength = value;
            }
            get
            {
                return iNumberLength;
            }
        }

        private long iNumberMax = 65536;

        [Description("数据最大值")]
        /// <summary>
        /// 数据长度
        /// </summary>
        public long INumberMax
        {
            set
            {
                iNumberMax = value;
            }
            get
            {
                return iNumberMax;
            }
        }

        private long iNumberMin = 0;

        [Description("数据最大值")]
        /// <summary>
        /// 数据长度
        /// </summary>
        public long INumberMin
        {
            set
            {
                iNumberMin = value;
            }
            get
            {
                return iNumberMin;
            }
        }

        public ushort Nushort{get => nushort;set => nushort = value;}
        public byte Nubyte { get => nubyte; set => nubyte = value; }
        public uint Nuint { get => nuint; set => nuint = value; }
        public ulong Nulong { get => nulong; set => nulong = value; }
        public byte[] Nbytes { get => nbytes; set => nbytes = value; }
        public byte[] Nushortbytes {
            get
            {
                return nushortbytes;
            }
            set
            {
                nushortbytes = value;
                nushort = (ushort)(nushortbytes[1] + (nushortbytes[0] << 8));
                this.Text = nushort.ToString();
            }
            
        }
        public byte[] Nuintbytes {
            get
            {
               return nuintbytes;
            }
            set
            {
                nuintbytes = value;
                nuint = (uint)(nuintbytes[3] + (nuintbytes[2] << 8) + (nuintbytes[1] << 16) + (nuintbytes[0] << 24));
                this.Text = nuint.ToString();
            }
        }
        public byte[] Nulongbytes { get => nulongbytes; set => nulongbytes = value; }
        #endregion

        private void TypeChange()
        {
            //if(numberType == NumberType.hexNumber)
            //    this.nushort = 65535;
            //else
            //{
            //    this.nushort = 12;
            //}
        }



        /// <summary>
        /// 重写 WndProc
        /// </summary>
        protected override void WndProc(ref Message m)
        {
            //如果该属性没有设置，则允许输入
            if (iNumberLength == 0)
            {
                base.WndProc(ref m);
                return;
            }

            switch (m.Msg)
            {
                case WM_CHAR:
                    int i = (int)m.WParam;
                    bool isBack = (i == (int)Keys.Back);
                    bool isDelete = (i == (int)Keys.Delete);//实际上这是一个"."键
                    bool isCtr = (i == 24) || (i == 22) || (i == 26) || (i == 3);

                    if (isBack || isDelete || isCtr)
                    {
                        //控制键不作处理
                        base.WndProc(ref m);
                    }
                    else
                    {
                        char c = (char)i;

                    }
                    base.WndProc(ref m);
                    break;
                case WM_PASTE:
                    IDataObject iData = Clipboard.GetDataObject();//取剪贴板对象
                    if (iData.GetDataPresent(DataFormats.Text)) //判断是否是Text
                    {
                        string text = (string)iData.GetData(DataFormats.Text);//取数据

                        m.Result = (IntPtr)0;//不可以粘贴

                    }
                    base.WndProc(ref m);
                    break;
                default:
                    base.WndProc(ref m);
                    break;
            }
        }

        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            base.OnKeyPress(e);

            if ( e.KeyChar == 8)
            {
                e.Handled = false;
                return;
            }

            if (numberType == NumberType.intNumber)
            {
                if (IsNum(e.KeyChar))
                    e.Handled = false;//允许输出
                else
                    e.Handled = true;//禁止输出
            }
            else
            {
                if (IsDecimal(e.KeyChar))
                    e.Handled = false;//允许输出
                else
                    e.Handled = true;//禁止输出
            }
        }

        private bool IsOutBoundary()
        {
            if (Convert.ToInt64(this.Text) > INumberMax || Convert.ToInt64(this.Text) < INumberMin)

                return true;
            else
                return false;

        }

        protected override void OnLeave(EventArgs e)
        {
            base.OnLeave(e);
            if (this.Text == "")
                return;
            if (Convert.ToInt64(this.Text) > INumberMax)
            {
                //this.Text = iNumberMax.ToString();
                MessageBox.Show("最大限制值为"+ iNumberMax, "提示:请修改", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                this.Focus();
            }

            else if (Convert.ToInt64(this.Text) < INumberMin)
            {
                //this.Text = iNumberMin.ToString();
                MessageBox.Show("最小限制值为" + iNumberMax, "提示：请修改", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                this.Focus();
            }
            else
            {
                this.Text = this.Text;
            }
        }

        private bool IsNum(char keyChar)
        {
            if ((keyChar >= 48 && keyChar <= 57))
            {
                if (this.Text.Trim().Length <= iNumberLength-1)
                    return true;
                else
                    return false;
            }
            else
                return false;

        }

        private bool IsDecimal(char keyChar)
        {
            if (((keyChar >= 48 && keyChar <= 57) || keyChar == 46))
            {
                if (this.Text.Trim().LastIndexOf('.') <= iNumberLength)
                {
                    if (this.Text.Trim().Contains(".") && keyChar == 46)
                        return false;
                    else
                        return true;
                }
                else
                {
                    if (keyChar != 8)
                    {
                        return false;
                    }
                    return true;
                }
            }
            else
                return false;

        }

        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);
            if (this.Text.Trim() != "")
            {
                this.nulong = Convert.ToUInt64(this.Text);
                Nulongbytes[7] = Nuintbytes[3] = Nushortbytes[1]= Nbytes[0]=(byte)(this.nulong & 0xFF);
                Nulongbytes[6] = Nuintbytes[2] = Nushortbytes[0]=(byte)(this.nulong >> 8 & 0xFF);
                Nulongbytes[5] = Nuintbytes[1] = (byte)(this.nulong >> 16 & 0xFF);
                Nulongbytes[4] = Nuintbytes[0] = (byte)(this.nulong >> 24 & 0xFF);
                Nulongbytes[3] = (byte)(this.nulong >> 32 & 0xFF);
                Nulongbytes[2] = (byte)(this.nulong >> 40 & 0xFF);
                Nulongbytes[1] = (byte)(this.nulong >> 48 & 0xFF);
                Nulongbytes[0] = (byte)(this.nulong >> 56 & 0xFF);
            }
            nubyte = Nulongbytes[7];
            nushort = (ushort)(Nulongbytes[7] + (Nulongbytes[6] << 8));
            nuint=(uint)(Nulongbytes[7] + Nulongbytes[6] << 8+ Nulongbytes[5] << 16+ Nulongbytes[4] << 24) ;
        }

    }
}
